﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Newtonsoft.Json.Linq;
using System.Text.RegularExpressions;

namespace HigLabo.Net.WindowsLive
{
    /// <summary>
    /// 
    /// </summary>
    public partial class WindowsLiveClient 
    {   
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        private String GetResponseBodyText(WindowsLiveCommand command)
        {
            String url = String.Format("https://apis.live.net/v5.0/{0}?access_token={1}{2}", command.GraphApiPath
                , HttpClient.UrlEncode(this.AccessToken.Value)
                , command.UrlParameter);
            url += String.Format("&callback={0}", Callbackkey);

            var cm = new HttpRequestCommand(url);
            cm.MethodName = command.MethodName;
            cm.ContentType = command.ContentType;

            if (command.MethodName == HttpMethodName.Post
             || command.MethodName == HttpMethodName.Put
             || command.MethodName == HttpMethodName.Move
             || command.MethodName == HttpMethodName.Copy)
            {
                cm.SetBodyStream(command.Data);
            }
            var text = this.GetBodyText(cm);
            var m = Regex.Match(text, @"{.*}", RegexOptions.IgnoreCase);
            if (Regex.IsMatch(m.Value, @"""error"": {.*code.*message.*}", RegexOptions.IgnoreCase))
            {
                throw new WindowsLiveInvalidResponseException(new WindowsLiveErrorResponse(m.Value));
            }
            return m.Value;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public User GetUser()
        {
            return this.GetUser(new GetUserCommand(""));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public User GetUser(String id)
        {
            return this.GetUser(new GetUserCommand(id));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public User GetUser(GetUserCommand command)
        {
            String text = this.GetResponseBodyText(command);
            return new User(text);
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public LiveObjectCollection GetFiles(GetFilesCommand command)
        {
            return new LiveObjectCollection(this.GetResponseBodyText(command));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public File GetFile(GetFileCommand command)
        {
            return new File(this.GetResponseBodyText(command));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="folderID"></param>
        /// <returns></returns>
        public Folder GetFolder(String folderID)
        {
            return new Folder(this.GetResponseBodyText(new WindowsLiveCommand(folderID)));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public Folder GetFolder(GetFolderCommand command)
        {
            return new Folder(this.GetResponseBodyText(command));
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileID"></param>
        /// <returns></returns>
        public File  GetFile(String fileID)
        {
            return new File(this.GetResponseBodyText(new WindowsLiveCommand(fileID)));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="photoID"></param>
        /// <returns></returns>
        public Photo GetPhoto(String photoID)
        {
            return new Photo(this.GetResponseBodyText(new WindowsLiveCommand(photoID)));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="videoID"></param>
        /// <returns></returns>
        public Video GetVideo(String videoID)
        {
            return new Video(this.GetResponseBodyText(new WindowsLiveCommand(videoID)));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="audioID"></param>
        /// <returns></returns>
        public Audio GetAudio(String audioID)
        {
            return new Audio(this.GetResponseBodyText(new WindowsLiveCommand(audioID)));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="albumID"></param>
        /// <returns></returns>
        public Album GetAlbum(String albumID)
        {
            return new Album(this.GetResponseBodyText(new WindowsLiveCommand(albumID)));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public ApplicationCollection GetApplications(GetApplicationsCommand command)
        {
            return new ApplicationCollection(this.GetResponseBodyText(command));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public Application CreateApplication(CreateApplicationCommand command)
        {
            return new Application(this.GetResponseBodyText(command));
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public File   UpdateFileProperties(UpdateFileCommand command)
        {
            return new File(this.GetResponseBodyText(command));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public Folder UpdateFolderProperties(UpdateFileCommand command)
        {
            return new Folder(this.GetResponseBodyText(command));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public Photo  UpdatePhotoProperties(UpdateFileCommand command)
        {
            return new Photo(this.GetResponseBodyText(command));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public Audio  UpdateAudioProperties(UpdateFileCommand command)
        {
            return new Audio(this.GetResponseBodyText(command));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public Video  UpdateVideoProperties(UpdateFileCommand command)
        {
            return new Video(this.GetResponseBodyText(command));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public Album  UpdateAlbumProperties(UpdateFileCommand command)
        {
            return new Album(this.GetResponseBodyText(command));
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileID"></param>
        /// <returns></returns>
        public String GetDownloadFilePath(String fileID)
        {
            Result result = new Result(this.GetResponseBodyText(new GetFileCommand(fileID, ActFLG.GetDownloadLink)));
            return result.Location;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileID"></param>
        /// <returns></returns>
        public Byte[] DownloadFile(String fileID)
        {
            var result = new Result(this.GetResponseBodyText(new GetFileCommand(fileID, ActFLG.GetDownloadLink)));
            var rs = this.GetHttpWebResponse(result.Location);
            return rs.GetResponseStream().ToByteArray();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        public String PostFile(PostFileCommand command)
        {
            Result result = new Result(this.GetResponseBodyText(command));
            return result.ID;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        public void DeleteFile(DeleteFileCommand command)
        {
            this.GetResponseBodyText(command);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        public void DeleteFolder(DeleteFolderCommand command)
        {
            this.GetResponseBodyText(command);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public Event GetEvent(GetEventCommand command)
        {
            return new Event(this.GetResponseBodyText(command));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public EventCollection GetEvents(GetEventsCommnad command)
        {
            return new EventCollection(this.GetResponseBodyText(command));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        public void DeleteEvent(DeleteEventCommand command)
        {
            this.GetResponseBodyText(command);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public Event CreateEvent(CreateEventCommand command)
        {
            return new Event(this.GetResponseBodyText(command));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public Permissions GetPermissions(GetPermissionsCommnad command)
        {
            return new Permissions(this.GetResponseBodyText(command));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public Tag GetTag(GetTagCommand command)
        {
            return new Tag(this.GetResponseBodyText(command));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public TagCollection GetTags(GetTagsCommnad command)
        {
            return new TagCollection(this.GetResponseBodyText(command));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public Result UploadFile(UploadFileCommand command)
        {
            Result result = new Result(this.GetResponseBodyText(command));
            return result;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public Folder CreateFolder(CreateFolderCommand command)
        {
            return new Folder(this.GetResponseBodyText(command));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public Album CreateAlbum(PostCommand command)
        {
            return new Album(this.GetResponseBodyText(command));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public Activity CreateActivity(CreateActivityCommand command)
        {
            return new Activity(this.GetResponseBodyText(command));
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        public void MoveFileFolder(MoveFileCommand command)
        {
            this.GetResponseBodyText(command);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        public void CopyFileFolder(CopyFileCommand command)
        {
            this.GetResponseBodyText(command);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public Contacts GetContacts(GetContactsCommand command)
        {
            return new Contacts(this.GetResponseBodyText(command));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public Contacts GetContacts()
        {
            return this.GetContacts(new GetContactsCommand());
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public CommentCollection GetComments(GetCommentsCommnad command)
        {
            return new CommentCollection(this.GetResponseBodyText(command));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="commentID"></param>
        /// <returns></returns>
        public Comment GetComment(String commentID)
        {
            return new Comment(this.GetResponseBodyText(new WindowsLiveCommand(commentID)));
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public CalendarCollection GetCalendars(GetCalendarsCommand command)
        {
            return new CalendarCollection(this.GetResponseBodyText(command));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="calendarID"></param>
        public Calendar GetCalendar(String calendarID)
        {
            return new Calendar(this.GetResponseBodyText(new WindowsLiveCommand(calendarID)));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public Calendar CreateCalendar(CreateCalendarCommand command)
        {
            return new Calendar(this.GetResponseBodyText(command));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public Calendar UpdateCalender(UpdateCalendarCommand command)
        {
            return new Calendar(this.GetResponseBodyText(command));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        public void DeleteCalendar(DeleteCalendarCommand command)
        {
            this.GetResponseBodyText(command);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public FriendCollertion GetFriends(GetFriendsCommand command)
        {
            return new FriendCollertion(this.GetResponseBodyText(command));
        }
    }
}

